#include "StateAttack.h"
#include "Logic/Entity/LivingEntity.h"
#include "Message/Message.h"
#include "Message/MessagePump.h"
#include "Logic/State/StateWalk.h"
#include "Logic/State/StateMachine.h"
#include "Scheduler/Scheduler.h"

int AttackOnceTask::count = 0;

void AttackOnceTask::Execute(int id, int time, void* pUser)
{
	StateAttack* pState = (StateAttack*)pUser;
	pState->AttackOnce();
	count--;
}


StateAttack::StateAttack(LivingEntity* parent) :State(FSM_STATE_ATTACK,parent)
{
	
}

void StateAttack::AttackOnce()
{
	LogicMsg data;
	data.time = m_owner->GetAttribute().walkSpeed * 20;
	data.direction = m_owner->GetDirection();
	DataMessage<LogicMsg>* newMsg = new DataMessage<LogicMsg>(MODULE_MSG|BROADCAST_MSG, MSGTYPE_ENTITY_ATTACK,data);
	newMsg->m_toID = m_owner->GetID();
	s_MessagePump->SendMsg(newMsg);

	DataMessage<LogicMsg>* newMsg2 = new DataMessage<LogicMsg>(ENTITY_MSG|UNICAST_MSG, MSGTYPE_ENTITY_HURT,data);
	newMsg2->m_toID = m_goalEntity->GetID();
	s_MessagePump->SendMsg(newMsg2);
}

void StateAttack::SetGoal(BaseGameEntity* pGoal)
{
	m_goalEntity = pGoal;
}

void StateAttack::Update(float dt)
{
	int dx = m_owner->GetPos().x() - m_goalEntity->GetPos().x();
	int dy = m_owner->GetPos().y() - m_goalEntity->GetPos().y();

	m_owner->SetDirection(-dx, -dy);
	if ( m_goalEntity->GetPos().Distance(m_owner->GetPos()) <= 1 )
	{
		//only execute once.
		if (AttackOnceTask::count == 0)
		{
			AttackOnceTask::count++;
			int excuteTime = s_Scheduler->GetClock().GetSystem() + m_owner->GetAttribute().walkSpeed * 20;
			s_Scheduler->Schedule(TASK_TIME, excuteTime, 0, -1, &m_attackTask, this, NULL);
		}
	}
	else
	{
		Vector2Di destCell;
		destCell.x() = dx < 0 ? m_goalEntity->GetPos().x()-1 : m_goalEntity->GetPos().x()+1;
		destCell.y() = dy < 0 ? m_goalEntity->GetPos().y()-1 : m_goalEntity->GetPos().y()+1;

		StateWalk* pNextState = (StateWalk *)m_owner->GetStateMachine()->GetState(FSM_STATE_WALK);
		pNextState->SetDestCell(Vector2Di(destCell));
		DataMessage<int>* newMsg = new DataMessage<int>(ENTITY_MSG|UNICAST_MSG, MSGTYPE_CHANGE_STATE,FSM_STATE_WALK);
		newMsg->m_toID = m_owner->GetID();
		newMsg->m_flag = ENTITY_MSG | UNICAST_MSG;
		s_MessagePump->SendMsg(newMsg);
	}

}
